package org.example.lethear.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.lethear.dto.common.PageResult;
import org.example.lethear.dto.user.UserDTO;
import org.example.lethear.dto.user.UserProfileDTO;
import org.example.lethear.dto.user.UserUpdateRequest;
import org.example.lethear.entity.Follow;
import org.example.lethear.entity.User;
import org.example.lethear.entity.UserProfile;
import org.example.lethear.exception.BusinessException;
import org.example.lethear.exception.ResourceNotFoundException;
import org.example.lethear.repository.*;
import org.example.lethear.utils.SecurityUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户管理服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
    
    private final UserRepository userRepository;
    private final UserProfileRepository userProfileRepository;
    private final PostRepository postRepository;
    private final CommentRepository commentRepository;
    private final FollowRepository followRepository;
    private final LikeRepository likeRepository;
    private final WhisperRepository whisperRepository;
    
    /**
     * 根据用户ID获取用户信息
     */
    public UserDTO getUserById(Long userId) {
        User user = userRepository.findByIdWithRoles(userId)
                .orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
        
        return convertToUserDTO(user);
    }
    
    /**
     * 根据用户名获取用户信息
     */
    public UserDTO getUserByUsername(String username) {
        User user = userRepository.findByUsernameWithRoles(username)
                .orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
        
        return convertToUserDTO(user);
    }
    
    /**
     * 获取当前用户信息
     */
    public UserDTO getCurrentUser() {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        return getUserById(currentUserId);
    }
    
    /**
     * 更新用户信息
     */
    @Transactional
    public UserDTO updateUser(UserUpdateRequest request) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        User user = userRepository.findByIdWithRoles(currentUserId)
                .orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
        
        // 更新基本信息
        if (StringUtils.hasText(request.getEmail())) {
            // 检查邮箱是否已被其他用户使用
            Optional<User> existingUser = userRepository.findByEmail(request.getEmail());
            if (existingUser.isPresent() && !existingUser.get().getId().equals(currentUserId)) {
                throw new BusinessException("邮箱已被其他用户使用");
            }
            user.setEmail(request.getEmail());
            user.setEmailVerified(false); // 更换邮箱后需要重新验证
        }
        
        if (StringUtils.hasText(request.getAvatar())) {
            user.setAvatar(request.getAvatar());
        }
        
        // 更新用户资料
        UserProfile profile = user.getProfile();
        if (profile == null) {
            profile = new UserProfile();
            profile.setUserId(user.getId());
            user.setProfile(profile);
        }
        
        if (StringUtils.hasText(request.getNickname())) {
            profile.setNickname(request.getNickname());
        }
        
        if (StringUtils.hasText(request.getBio())) {
            profile.setBio(request.getBio());
        }
        
        if (StringUtils.hasText(request.getPhone())) {
            profile.setPhone(request.getPhone());
        }
        
        if (request.getBirthday() != null) {
            profile.setBirthday(request.getBirthday());
        }
        
        if (request.getGender() != null) {
            // 将字符串转换为Integer
            try {
                profile.setGender(Integer.valueOf(request.getGender()));
            } catch (NumberFormatException e) {
                profile.setGender(0); // 默认为保密
            }
        }
        
        // 保存更新
        user = userRepository.save(user);
        
        log.info("用户信息更新成功: {}", user.getUsername());
        
        return convertToUserDTO(user);
    }
    
    /**
     * 关注用户
     */
    @Transactional
    public void followUser(Long targetUserId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        if (currentUserId.equals(targetUserId)) {
            throw new BusinessException("不能关注自己");
        }
        
        // 检查目标用户是否存在
        User targetUser = userRepository.findById(targetUserId)
                .orElseThrow(() -> new ResourceNotFoundException("目标用户不存在"));
        
        // 检查是否已经关注
        if (followRepository.existsByFollowerIdAndFollowingId(currentUserId, targetUserId)) {
            throw new BusinessException("已经关注过该用户");
        }
        
        // 创建关注关系
        Follow follow = new Follow();
        follow.setFollowerId(currentUserId);
        follow.setFollowingId(targetUserId);
        followRepository.save(follow);
        
        log.info("用户关注成功: {} 关注了 {}", currentUserId, targetUserId);
    }
    
    /**
     * 取消关注用户
     */
    @Transactional
    public void unfollowUser(Long targetUserId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 删除关注关系
        followRepository.deleteByFollowerIdAndFollowingId(currentUserId, targetUserId);
        
        log.info("取消关注成功: {} 取消关注了 {}", currentUserId, targetUserId);
    }
    
    /**
     * 检查是否关注了指定用户
     */
    public boolean isFollowing(Long targetUserId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return false;
        }
        
        return followRepository.existsByFollowerIdAndFollowingId(currentUserId, targetUserId);
    }
    
    /**
     * 获取用户的关注列表
     */
    public PageResult<UserDTO> getFollowing(Long userId, int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by("createdAt").descending());
        Page<Follow> followPage = followRepository.findByFollowerId(userId, pageable);
        
        List<UserDTO> userDTOs = followPage.getContent().stream()
                .map(follow -> getUserById(follow.getFollowingId()))
                .collect(Collectors.toList());
        
        return PageResult.of(userDTOs, followPage.getTotalElements(), page, size);
    }
    
    /**
     * 获取用户的粉丝列表
     */
    public PageResult<UserDTO> getFollowers(Long userId, int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by("createdAt").descending());
        Page<Follow> followPage = followRepository.findByFollowingId(userId, pageable);
        
        List<UserDTO> userDTOs = followPage.getContent().stream()
                .map(follow -> getUserById(follow.getFollowerId()))
                .collect(Collectors.toList());
        
        return PageResult.of(userDTOs, followPage.getTotalElements(), page, size);
    }
    
    /**
     * 搜索用户
     */
    public PageResult<UserDTO> searchUsers(String keyword, int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by("createTime").descending());
        Page<User> userPage;
        
        // 使用预加载角色的查询方法，避免懒加载异常
        if (keyword != null && !keyword.trim().isEmpty()) {
            userPage = userRepository.searchUsersWithRoles(keyword.trim(), pageable);
        } else {
            userPage = userRepository.findAllWithRoles(pageable);
        }
        
        List<UserDTO> userDTOs = userPage.getContent().stream()
                .map(this::convertToUserDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(userDTOs, userPage.getTotalElements(), page, size);
    }
    
    /**
     * 获取用户统计信息
     */
    public UserDTO.UserStats getUserStats(Long userId) {
        // 使用优化的count查询方法
        Long postCount = postRepository.countByUserId(userId);
        Long commentCount = commentRepository.countByUserId(userId);
        Long followingCount = followRepository.countFollowing(userId);
        Long followerCount = followRepository.countFollowers(userId);
        Long likeCount = likeRepository.countByUserId(userId);
        Long whisperCount = whisperRepository.countBySenderId(userId);
        
        return UserDTO.UserStats.builder()
                .postCount(postCount)
                .commentCount(commentCount)
                .followingCount(followingCount)
                .followerCount(followerCount)
                .likeCount(likeCount)
                .whisperCount(whisperCount)
                .build();
    }


    
    /**
     * 为管理员页面转换User实体为简化的UserDTO（不包含复杂统计）
     */
    public UserDTO convertToSimpleUserDTO(User user) {
        UserDTO.UserDTOBuilder builder = UserDTO.builder()
                .id(user.getId())
                .username(user.getUsername())
                .email(user.getEmail())
                .avatar(user.getAvatar())
                .status(user.getStatus()) // 设置status字段
                .enabled(user.isEnabled())
                .emailVerified(user.isEmailVerified())
                .lastLoginTime(user.getLastLoginTime())
                .createdAt(user.getCreateTime())
                .updatedAt(user.getUpdateTime());
        
        // 角色信息
        if (user.getRoles() != null) {
            builder.roles(user.getRoles().stream()
                    .map(role -> role.getRoleName())
                    .collect(Collectors.toSet()));
        }
        
        // 用户资料信息
        if (user.getProfile() != null) {
            builder.profile(convertToUserProfileDTO(user.getProfile()));
        }
        
        // 为管理员页面提供基本统计信息（避免复杂查询）
        UserDTO.UserStats basicStats = UserDTO.UserStats.builder()
                .postCount(0L)
                .commentCount(0L)
                .followingCount(0L)
                .followerCount(0L)
                .likeCount(0L)
                .whisperCount(0L)
                .build();
        builder.stats(basicStats);
        
        return builder.build();
    }
    
    /**
     * 转换User实体为UserDTO
     */
    private UserDTO convertToUserDTO(User user) {
        UserDTO.UserDTOBuilder builder = UserDTO.builder()
                .id(user.getId())
                .username(user.getUsername())
                .email(user.getEmail())
                .avatar(user.getAvatar())
                .status(user.getStatus()) // 设置status字段
                .enabled(user.isEnabled())
                .emailVerified(user.isEmailVerified())
                .lastLoginTime(user.getLastLoginTime())
                .createdAt(user.getCreateTime())
                .updatedAt(user.getUpdateTime());
        
        // 设置nickname（从profile中获取）
        if (user.getProfile() != null && user.getProfile().getNickname() != null) {
            builder.nickname(user.getProfile().getNickname());
        }
        
        // 角色信息
        if (user.getRoles() != null) {
            builder.roles(user.getRoles().stream()
                    .map(role -> role.getRoleName())
                    .collect(Collectors.toSet()));
        }
        
        // 用户资料信息
        if (user.getProfile() != null) {
            builder.profile(convertToUserProfileDTO(user.getProfile()));
        }
        
        // 统计信息
        builder.stats(getUserStats(user.getId()));
        
        return builder.build();
    }
    
    /**
     * 转换UserProfile实体为UserProfileDTO
     */
    private UserProfileDTO convertToUserProfileDTO(UserProfile profile) {
        return UserProfileDTO.builder()
                .id(profile.getId())
                .nickname(profile.getNickname()) // 直接映射nickname
                .bio(profile.getBio())
                .phone(profile.getPhone())
                .birthday(profile.getBirthday())
                .gender(profile.getGender() != null ? profile.getGender().toString() : "0") // 转换为字符串
                .createdAt(profile.getCreateTime())
                .updatedAt(profile.getUpdateTime())
                .build();
    }
} 